/**
 * Copyright (c) 2022,TravelSky. 
 * All Rights Reserved.
 * TravelSky CONFIDENTIAL
 * 
 * Project Name:ddserver
 * Package Name:com.asb.controller
 * File Name:IndexController.java
 * Date:2022年3月17日 下午12:04:11
 * 
 */
package com.asb.controller;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.asb.model.AuditOrder;
import com.asb.model.PeopleInfo;
import com.asb.service.OrderService;
import com.asb.service.PeopleService;
import com.asb.service.UserDingTalkService;
import com.asb.utils.AccessUtil;
import com.asb.utils.DingCallbackCrypto;
import com.asb.utils.DingCallbackCrypto.DingTalkEncryptException;
import com.asb.utils.HttpTools;
import com.asb.utils.JsonUtil;
import com.asb.utils.PropertiesKit;
import com.asb.utils.Strings;
import com.asb.vo.OperationRecordsVO;
import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.OapiProcessinstanceGetRequest;
import com.dingtalk.api.response.OapiProcessinstanceGetResponse;
import com.jfinal.aop.Inject;
import com.jfinal.core.ActionKey;
import com.jfinal.core.Controller;
import com.jfinal.core.Path;
import com.jfinal.ext.cors.EnableCORS;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;
import com.taobao.api.ApiException;

/**
 * ClassName: IndexController <br/>
 * Description: TODO <br/>
 * Date: 2022年3月17日 下午12:04:11 <br/>
 * <br/>
 * 
 * @author 1(邮箱)
 * 
 *         修改记录
 * @version 产品版本信息 yyyy-mm-dd 姓名(邮箱) 修改信息<br/>
 * 
 */

@Path("/callback")
@EnableCORS
public class CallbackController extends Controller {

	public static Logger log = Logger.getLogger(CallbackController.class);

	@Inject
	OrderService orderService;

	@Inject
	UserDingTalkService userService;

	@Inject
	PeopleService peopleService;

	public void process() {
		try {
			String msg_signature = this.getPara("msg_signature");
			String timeStamp = this.getPara("timestamp");
			String nonce = this.getPara("nonce");
			String body = HttpTools.readBody(this.getRequest());
			JSONObject json = JSONObject.parseObject(body);
			log.info("msg_signature: " + Strings.nullToSpace(msg_signature) + " timeStamp: "
					+ Strings.nullToSpace(timeStamp) + " nonce: " + Strings.nullToSpace(nonce) + " body: "
					+ Strings.nullToSpace(body));
			// 1. 从http请求中获取加解密参数
			// 2. 使用加解密类型
			// Constant.OWNER_KEY 说明：
			// 1、开发者后台配置的订阅事件为应用级事件推送，此时OWNER_KEY为应用的APP_KEY。
			// 2、调用订阅事件接口订阅的事件为企业级事件推送，
			// 此时OWNER_KEY为：企业的appkey（企业内部应用）或SUITE_KEY（三方应用）
			DingCallbackCrypto callbackCrypto = new DingCallbackCrypto(PropertiesKit.geTaes_token(),
					PropertiesKit.getAes_key(), PropertiesKit.getAppkey());
			String encryptMsg = json.getString("encrypt");
			log.info("encryptMsg: " + encryptMsg);
			String decryptMsg = callbackCrypto.getDecryptMsg(msg_signature, timeStamp, nonce, encryptMsg);
			// 3. 反序列化回调事件json数据
			JSONObject eventJson = JSON.parseObject(decryptMsg);
			String eventType = eventJson.getString("EventType");
			log.info("eventJson: " + eventJson);

			// 4. 根据EventType分类处理
			if ("check_url".equals(eventType)) {
				// 测试回调url的正确性
				log.info("测试回调url的正确性");
			} else if ("bpms_instance_change".equals(eventType)) {
				// OA审批回调
				log.info("发生了：" + eventType + "事件");
				String typer = eventJson.getString("type");
				String result = eventJson.getString("result");
				if ("finish".equals(typer)) {
					String processInstanceId = eventJson.getString("processInstanceId");
					DingTalkClient client = new DefaultDingTalkClient(
							"https://oapi.dingtalk.com/topapi/processinstance/get");
					OapiProcessinstanceGetRequest req = new OapiProcessinstanceGetRequest();
					req.setProcessInstanceId(processInstanceId);
					try {
						OapiProcessinstanceGetResponse rsp = client.execute(req, AccessUtil.getAccess_token());
						log.info("OA实例详情: " + rsp.getBody());
						String processString = rsp.getBody();
						List<OperationRecordsVO> operationRecordsList = (List<OperationRecordsVO>) JSONObject
								.parseArray(String.valueOf(JsonUtil.toProcess(processString).get("operation_records")),
										OperationRecordsVO.class);

						Map<String, Object> idMap = this.selectIdByTask(processInstanceId);
						if (idMap == null) {
							log.info("-----无法通过实例获取主表业务号-----");
							return;
						}
						AuditOrder order = new AuditOrder();
						String userid = "";
						// 同意
						if ("agree".equals(result)) {
							log.info("agree：同意");
							for (OperationRecordsVO vo : operationRecordsList) {
								if ("AGREE".equals(vo.getOperation_result())) {
									userid = vo.getUserid();
									Map<String, Object> userMap = this.getLeaderInfo(userid);
									if (userMap == null) {
										log.info(userid + ": -----查询无此用户-----");
										continue;
									}
									order.setId(Long.parseLong(idMap.get("id").toString()));
									order.setIsleaderpass("是 ");
									order.setLeaderuser(String.valueOf(userMap.get("username")));
									order.setLeadername(String.valueOf(userMap.get("name")));
									order.setLeaderopinion(vo.getRemark());
									Map<String, Object> resultMap = orderService.audit(order);
									resultMap.forEach((k, v) -> log.info("auditKey:auditValue = " + k + ":" + v));
								}
							}
						}
						// 拒绝
						if ("refuse".equals(result)) {
							log.info("refuse：拒绝");
							for (OperationRecordsVO vo : operationRecordsList) {
								if ("REFUSE".equals(vo.getOperation_result())) {
									userid = vo.getUserid();
									Map<String, Object> userMap = this.getLeaderInfo(userid);
									if (userMap == null) {
										log.info(userid + ": -----查询无此用户-----");
										continue;
									}
									order.setId(Long.parseLong(idMap.get("id").toString()));
									order.setIsleaderpass("否");
									order.setLeaderuser(String.valueOf(userMap.get("username")));
									order.setLeadername(String.valueOf(userMap.get("name")));
									order.setLeaderopinion(vo.getRemark());
									Map<String, Object> resultMap = orderService.audit(order);
									resultMap.forEach((k, v) -> log.info("auditKey:auditValue = " + k + ":" + v));
								}
							}

						}

					} catch (ApiException e) {
						// TODO Auto-generated catch block
						log.error("", e);
					}
				}

			} else {
				// 添加其他已注册的
				log.info("发生了：" + eventType + "事件");
			}

			// 5. 返回success的加密数据
			Map<String, String> successMap = callbackCrypto.getEncryptedMap("success");

			this.renderJson(successMap);

		} catch (DingTalkEncryptException e) {
			log.error("", e);
		}
	}

	/**
	 * 根据单号获取信息-钉钉的task表-DB
	 **/
	public Map<String, Object> selectIdByTask(String processInstanceId) {
		StringBuffer buffer = new StringBuffer();
		buffer.append(" SELECT id");
		buffer.append(" FROM dingtalk_task ");
		buffer.append(" WHERE task_id=? ");
		buffer.append(" ORDER BY createtime desc ");
		Record record = Db.findFirst(buffer.toString(), processInstanceId);
		if (record == null)
			return null;
		Map<String, Object> map = record.toMap();
		return map;
	}

	private Map<String, Object> getLeaderInfo(String userid) {
		String detailStr = userService.getUserDetail(userid);
		List<Map<String, Object>> list = new ArrayList<>();
		try {
			Map<String, Object> map2 = JsonUtil.toRes(detailStr);
			String mobile = String.valueOf(map2.get("mobile"));
			List<String> mobiles = new ArrayList<>();
			mobiles.add(mobile);
			PeopleInfo people = new PeopleInfo();
			people.setMobile(mobiles);
			people.setUserId(userid);
			list = peopleService.getPeopleInfoFor(people);
		} catch (ApiException e) {
			// TODO Auto-generated catch block
			log.error("", e);
		}
		if (list == null || list.size() <= 0)
			return null;

		return list.get(0);
	}

}
